package com.seeingtv.interceptor;

import com.seeingtv.common.exception.user.*;
import com.seeingtv.common.utils.security.ShiroUtils;
import com.seeingtv.model.User;
import com.seeingtv.service.MenuService;
import com.seeingtv.service.RoleService;
import com.seeingtv.service.login.LoginService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * @author hubert
 * @date 2017-11-11
 * */
public class ShiroRealm extends AuthorizingRealm{
    private static final Logger logger = LoggerFactory.getLogger(ShiroRealm.class);

    @Autowired
    private MenuService menuService;

    @Autowired
    private LoginService loginService;

    @Autowired
    private RoleService roleService;

    /**
     * 用户授权认证
	 * jsp中带有shiro标签才会去加载权限认证或者调用SecurityUtils.getSubject().isPermitted(String str)时加载
	 * 会缓存
	 * AuthorizationInfo 缓存在shiro-ehcache中
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		Long userId = ShiroUtils.getUserId();
		//SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		// 角色加入AuthorizationInfo认证对象，角色关键字
		//info.setRoles(roleService.selectRoleKeys(userId));
		// 权限加入AuthorizationInfo认证对象，按钮关键字
		//info.setStringPermissions(menuService.selectPermsByUserId(userId));
		return null;
    }
    /**
     * 用户登陆认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		String username = upToken.getUsername();
		String password = "";
		if (upToken.getPassword() != null) {
			password = new String(upToken.getPassword());
		}

		User user = null;
		try {
			user = loginService.login(username, password);
		} catch (CaptchaException e) {
			throw new AuthenticationException(e.getMessage(), e);
		} catch (UserNotExistsException e) {
			throw new UnknownAccountException(e.getMessage(), e);
		} catch (UserPasswordNotMatchException e) {
			throw new IncorrectCredentialsException(e.getMessage(), e);
		} catch (UserPasswordRetryLimitExceedException e) {
			throw new ExcessiveAttemptsException(e.getMessage(), e);
		} catch (UserBlockedException e) {
			throw new LockedAccountException(e.getMessage(), e);
		} catch (RoleBlockedException e) {
			throw new LockedAccountException(e.getMessage(), e);
		} catch (Exception e) {
			logger.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
			throw new AuthenticationException(e.getMessage(), e);
		}
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
		return info;
    }

	/**
	 * 清理缓存权限
	 */
	public void clearCachedAuthorizationInfo() {
		this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
	}

}
